package com.joyxy.easy.service;

import cn.hutool.log.Log;
import cn.sanenen.dm.base.DmApi;
import cn.sanenen.dm.common.constant.KeyConstants;
import com.joyxy.easy.entity.WindowContext;
import com.joyxy.easy.monitor.StatusMonitor;
import com.joyxy.easy.manger.WindowManager;

public class MoveService {
    private static final Log log = Log.get();
    private final long hwnd;


    private static final int PRECISION_THRESHOLD = 50;  // 精确移动阈值
    private static final int LONG_PRESS_DELAY = 100;     // 长按基准时间(ms)
    private static final int TAP_DELAY = 50;

    public MoveService(long hwnd) {
        this.hwnd = hwnd;
    }

    public void move(long targetX, Long face) {
        StatusMonitor monitor = WindowManager.getContext(hwnd).getMonitor();
        DmApi dmApi = WindowManager.getContext(hwnd).getDmApi();
        monitor.setMove(true);
        try {
            while (true) {
                long currentX = monitor.nowX();
                long distance = targetX - currentX;
                long absDistance = Math.abs(distance);
                if (absDistance <= 5) {
                    if (face != null) {
                        long nowFace = monitor.nowFace();
                        if (!face.equals(nowFace)) {
                            if (face == 0) {
                                dmApi.KeyPress(KeyConstants.LEFT);
                            } else {
                                dmApi.KeyPress(KeyConstants.RIGHT);
                            }
                        }
                    }
                    return;
                }
                // 确定移动方向
                int directionKey = distance > 0 ? KeyConstants.RIGHT : KeyConstants.LEFT;


                if (absDistance > PRECISION_THRESHOLD) {
                    // 大距离：长按移动
                    longPressMove(directionKey, absDistance);
                } else {
                    // 小距离：精确点按
                    preciseMove(directionKey, absDistance, targetX);
                }
                Thread.sleep(100);
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
//            // 确保释放所有按键
            releaseDirectionKeys();
            monitor.setMove(false);
        }
    }

    private void releaseDirectionKeys() {
        WindowContext context = WindowManager.getContext(hwnd);
        DmApi dmApi = context.getDmApi();
        dmApi.KeyUp(KeyConstants.RIGHT);
        dmApi.KeyUp(KeyConstants.LEFT);
    }

    /**
     * 长按移动（粗略移动）
     */
    private void longPressMove(int direction, long distance) throws InterruptedException {
        // 计算长按时间（动态调整）
        int pressTime = (int) Math.min(
                LONG_PRESS_DELAY * (distance / PRECISION_THRESHOLD),
                1000  // 最大不超过1秒
        );
        WindowContext context = WindowManager.getContext(hwnd);
        DmApi dmApi = context.getDmApi();
        dmApi.KeyDown(direction);
        Thread.sleep(pressTime);
        dmApi.KeyUp(direction);
    }

    /**
     * 精确点按移动
     */
    private void preciseMove(int direction, long distance, long targetX) throws InterruptedException {
        WindowContext context = WindowManager.getContext(hwnd);
        DmApi dmApi = context.getDmApi();
        dmApi.KeyDown(direction);
        Thread.sleep(50);
        dmApi.KeyUp(direction);
        Thread.sleep(TAP_DELAY);
    }


    public void moveLeftRight(int i) {
        WindowContext context = WindowManager.getContext(hwnd);
        StatusMonitor monitor = context.getMonitor();
        DmApi dmApi = context.getDmApi();
        try {
            Thread.sleep(500);
            dmApi.KeyDown(KeyConstants.LEFT);
            Thread.sleep(100L * i);
            dmApi.KeyUp(KeyConstants.LEFT);
            Thread.sleep(500);

            dmApi.KeyDown(KeyConstants.RIGHT);
            Thread.sleep(100L * 2 * i);
            dmApi.KeyUp(KeyConstants.RIGHT);
            Thread.sleep(500);

            dmApi.KeyDown(KeyConstants.LEFT);
            Thread.sleep(100L * i);
            dmApi.KeyUp(KeyConstants.LEFT);
            Thread.sleep(500);
        } catch (Exception e) {
            log.error(e);
        } finally {
            releaseDirectionKeys();
        }

    }
}
